﻿using System;
using NLog;
using NUnit.Framework;
using ScrappyDB.Attributes;
using ScrappyDB.BaseClasses;

namespace ScrappyDB.IntegrationTests.Core
{


    /// <summary>
    ///This is a test class for SimpleDbCollectionTest and is intended
    ///to contain all SimpleDbCollectionTest Unit Tests
    ///</summary>
    [TestFixture]
    public class SdbCollectionTest 
    {
        // Create a logger for use in this class
        private static readonly Logger log = LogManager.GetCurrentClassLogger();

        public static Guid TestIdGuid = Guid.Empty;
        public static string TestIdString = TestIdGuid.ToString();
        public static string TestString = "Test123";
        public static int TestInt = 1234;
        public static int TestNegativeInt = -5678;
        public static DateTime TestDate = DateTime.Now.ToUniversalTime();

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
 
        [SetUp]
        public void MyTestInitialize()
        {
            Cleanup();
        }

        //Use TestCleanup to run code after each test has run
        [TearDown]
        public void MyTestCleanup()
        {
            Cleanup();
        }

        private void Cleanup()
        {
            try
            {
                var db = new Db();
                var a = db.Query<TestItem>(null, true);

                foreach (var i in a)
                {
                    db.Delete(i);
                }

                var b = db.Query<TestItemWithNestedCollection>(null, true);

                foreach (var i in b)
                {
                    db.Delete(i);
                }

                var r = db.Query<Relationship>(" ParentEntityType = 'TestItemWithNestedCollection'", true);

                foreach (var q in r)
                {
                    db.Delete(q);
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }
        }

        #endregion




        class TestCollection : SdbCollection<TestItemWithNestedCollection>
        { }

        [DomainName("ScrappyDB_UnitTests"), EntityName("TestItem")]
        class TestItem 
        {
            public Guid Id { get; set; }
            public string TestString { get; set; }
        }

        [DomainName("ScrappyDB_UnitTests"), EntityName("TestItemWithNestedCollection")]
        class TestItemWithNestedCollection 
        {
            public Guid Id { get; set; }
            public string TestString { get; set; }
            public SdbCollection<TestItemWithNestedCollection> NestedCollection { get; set; }
        }


        [Test()]
        public void NestCollectionTest()
        {
            var a = new TestCollection
                        {
                            new TestItemWithNestedCollection()
                                {
                                    Id = Guid.NewGuid(), 
                                    TestString = "test1"
                                }
                        };

            a[0].NestedCollection = new SdbCollection<TestItemWithNestedCollection>
                                        {
                                            new TestItemWithNestedCollection()
                                                {
                                                    Id = Guid.NewGuid(), 
                                                    TestString = "test2"
                                                }
                                        };

            var p = new TestItemWithNestedCollection
                        {
                            Id = TestIdGuid, 
                            TestString = TestString, 
                            NestedCollection = a
                        };

            var db = new Db();
            db.SaveChanges(p);

            var b = db.Find<TestItemWithNestedCollection>(TestIdString,true);

            Assert.AreEqual(TestString, b.TestString);

            Assert.AreEqual(1, b.NestedCollection.Count);
            Assert.AreEqual("test1", b.NestedCollection[0].TestString);
            Assert.AreEqual("test2", b.NestedCollection[0].NestedCollection[0].TestString);
        }

        [Test()]
        public void BasicCollectionTest()
        {
            var a = new SdbCollection<TestItem>();
            a.Add(new TestItem() { Id = Guid.NewGuid(), TestString = "test1" });
            a.Add(new TestItem() { Id = Guid.NewGuid(), TestString = "test2" });
            a.Add(new TestItem() { Id = Guid.NewGuid(), TestString = "test3" });

            var db = new Db();
            a.SaveChanges();

            var b = db.Query<TestItem>(null, true);

            Assert.AreEqual(3, b.Count);
        }

        [Test()]
        public void BatchPutCollectionTest()
        {
            var a = new SdbCollection<TestItem>();

            for (int x = 0; x < 65; x++)
            {
                a.Add(new TestItem() { Id = Guid.NewGuid(), TestString = "test" + x.ToString() });
            }

            a.SaveChanges();

            var db = new Db();
            var b = db.Query<TestItem>(null, true);

            Assert.AreEqual(65, b.Count);
        }
    }
}
